package com.xoa.global.timedTask;

import com.alibaba.fastjson.JSON;
import com.xoa.dao.attend.*;
import com.xoa.dao.attendance.AttendRuleMapper;
import com.xoa.dao.attendance.UserDutyMapper;
import com.xoa.dao.department.DepartmentMapper;
import com.xoa.dao.users.UserExtMapper;
import com.xoa.dao.users.UsersMapper;
import com.xoa.model.attend.Attend;
import com.xoa.model.attend.AttendMachine;
import com.xoa.model.attendance.UserDuty;
import com.xoa.service.attend.wrapper.TransactionResponse;
import com.xoa.util.DateFormat;
import com.xoa.util.ToJson;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by 刘建 on 2020/7/12 15:34
 * 定时任务-考勤机同步考勤信息
 * com.xoa.service.attend.AttendService.synAttend()
 */
@Component
public class SyncAttend {

    @Value("${upload.win}")
    private String savePath_win;

    @Value("${upload.linux}")
    private String savePath_linux;

    @Autowired
    private AttendMapper attendMapper;

    @Autowired
    private UserDutyMapper userDutyMapper;

    @Autowired
    private AttendMachineMapper attendMachineMapper;


    public ToJson synAttend(String beginDate, String endDate) {
        List<AttendMachine> attendMachine = attendMachineMapper.selectMachine(new AttendMachine());
        if (attendMachine != null && attendMachine.size() > 0) {
            AttendMachine machine = attendMachine.get(0);
            String url = machine.getDatabaseIp();
            Map<String, Object> map = new HashMap<String, Object>();
            String sn = machine.getMachineBrand();
            map.put("starttime", beginDate);
            map.put("sn", sn);
            map.put("endtime", endDate);
            String param = com.alibaba.fastjson.JSONObject.toJSONString(map);
            String result = sendPost(url, param);
            List<Attend> attends = new ArrayList<>();
            if (result != null && !result.equals("")) {
                //反序列化转换对象
                TransactionResponse transactionResponse = JSON.parseObject(result, TransactionResponse.class);
                //System.out.println(transactionResponse);
                TransactionResponse.DataBean tdataBean = transactionResponse.getData();
                if (tdataBean != null) {
                    //获取数据
                    List<TransactionResponse.DataBean.ItemsBean> itemsBeans = tdataBean.getItems();
                    if (itemsBeans != null && itemsBeans.size() > 0) {
                        //按pin分组，创建set接受唯一pin
                        Set<String> pinSet = new HashSet<>();
                        for (TransactionResponse.DataBean.ItemsBean itemsBeana : itemsBeans) {
                            pinSet.add(itemsBeana.getPin());
                        }
                        //分组  创建map接受分组的数据
                        Map<String, List<TransactionResponse.DataBean.ItemsBean>> pinMap = new HashMap<>();
                        for (String pin : pinSet) {
                            List<TransactionResponse.DataBean.ItemsBean> itemsBeanList = new ArrayList<>();
                            for (TransactionResponse.DataBean.ItemsBean itemsBean : itemsBeans) {
                                if (pin.trim().equals(itemsBean.getPin().trim())) {
                                    itemsBeanList.add(itemsBean);
                                }
                            }
                            pinMap.put(pin, itemsBeanList);
                        }
                        //获取俩个日期中的所有日期
                        List<String> days = getDays(beginDate.split(" ")[0], endDate.split(" ")[0]);
                        //获取这些人的排班 数据
                        Map queryUserDutyMap = new HashMap();
                        queryUserDutyMap.put("pinSet", pinSet);
                        queryUserDutyMap.put("beginDate", beginDate.split(" ")[0]);
                        queryUserDutyMap.put("endDate", endDate.split(" ")[0]);
                        List<UserDuty> userDutyList = userDutyMapper.getUserDutyListByUserIdsAndDates(queryUserDutyMap);
                        if (userDutyList != null && userDutyList.size() > 0) {
                            //分组这些人的考勤
                            Map<String, List<UserDuty>> userDutyMap = groupUserDuty(pinSet, userDutyList);
                            if (userDutyMap != null) {
                                //检索每个人的考勤记录
                                for (String pin : pinSet) {
                                    //用户这期间排班情况
                                    List<UserDuty> userDutys = userDutyMap.get(pin);
                                    if (userDutys != null && userDutys.size() > 0) {
                                        //同步过来的记录
                                        List<TransactionResponse.DataBean.ItemsBean> itemsBeanList = pinMap.get(pin);
                                        Map<String, List<TransactionResponse.DataBean.ItemsBean>> dayItemsBeans = new HashMap<>();
                                        //按日期分组同步过来的数据
                                        for (String day : days) {
                                            List<TransactionResponse.DataBean.ItemsBean> dayDataBean = new ArrayList<>();
                                            for (TransactionResponse.DataBean.ItemsBean itemsBean : itemsBeanList) {
                                                if (itemsBean.getChecktime().contains(day)) {
                                                    dayDataBean.add(itemsBean);
                                                }
                                            }
                                            dayItemsBeans.put(day, dayDataBean);
                                        }
                                        //按日期分组用户的排班情况
                                        Map<String, UserDuty> userDutyMaps = new HashMap<>();
                                        for (String day : days) {
                                            for (UserDuty userDuty : userDutys) {
                                                if (userDuty.getDutyDate().equals(day)) {
                                                    userDutyMaps.put(day, userDuty);
                                                }
                                            }
                                        }
                                        //循环得到每一天
                                        for (String day : days) {
                                            //查看今天是否有排班？
                                            UserDuty userDuty = userDutyMaps.get(day);
                                            if (userDuty != null) {
                                                //查看用户今天是否已经有了签到记录，防止重复录入
                                                Integer res = attendMapper.getUidDateAttend(day, userDuty.getUid());
                                                if (res == null) {
                                                    List<TransactionResponse.DataBean.ItemsBean> dayItemsBeanList = dayItemsBeans.get(day);
                                                    if (dayItemsBeanList != null && dayItemsBeanList.size() > 0) {
                                                        //按时间分组
                                                        paixuAttend(dayItemsBeanList);
                                                        //当天最早签到记录
                                                        TransactionResponse.DataBean.ItemsBean itemsBean = dayItemsBeanList.get(0);
                                                        Attend attend = new Attend();
                                                        attend.setType("1");
                                                        attend.setUid(userDuty.getUid());
                                                        attend.setDate(DateFormat.DateToStr(day));
                                                        attend.setAtime(DateFormat.getTime(itemsBean.getChecktime()));
                                                        attend.setPhoneId("kaoqinji");
                                                        attend.setDevice(sn);
                                                        attend.setAddress("考勤机");
                                                        attend.setRemark("考勤机数据");
                                                        attends.add(attend);
                                                    }
                                                }
                                            }

                                        }

                                    }

                                }
                            }
                        }
                    }
                }
            }
            if (attends != null && attends.size() > 0) {
                int res = attendMapper.insertAttends(attends);
            }
            FileWriter osw = null;
            try {
                //输出日志
                String path = this.getClass().getResource("/").getPath().replaceFirst("/", "");
                String savePath = "";
                //如果是windows
                if (File.separator.equals("\\")) {
                    String[] split = path.split("webapps");
                    savePath = split[0] + savePath_win + "/attendBak";
                } else if (File.separator.equals("/")) {
                    String[] split = path.split("tomcat");
                    savePath = split[0] + savePath_linux + "/attendBak";
                }
                File file = new File(savePath);
                if (!file.exists()) {
                    file.mkdir();
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
                String time = sdf.format(new Date());
                osw = new FileWriter(savePath + "/synAttnd" + time + ".txt", true);
                osw.write("得到的数据：   ");
                osw.write(result);
                osw.write("成功同步数据：   ");
                osw.write(attends.toString());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (osw != null) {
                    try {
                        osw.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        ToJson toJson = new ToJson(0, "成功");
        return toJson;
    }
    /**
     * 获取两个日期之间的所有日期
     *
     * @param startTime 开始日期
     * @param endTime   结束日期
     * @return
     */
    public static List<String> getDays(String startTime, String endTime) {
        if (startTime.length() > 10) {
            startTime = startTime.split(" ")[0];
        }
        if (endTime.length() > 10) {
            endTime = endTime.split(" ")[0];
        }
        // 返回的日期集合
        List<String> days = new ArrayList<String>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date start = dateFormat.parse(startTime);
            Date end = dateFormat.parse(endTime);

            Calendar tempStart = Calendar.getInstance();
            tempStart.setTime(start);

            Calendar tempEnd = Calendar.getInstance();
            tempEnd.setTime(end);
            tempEnd.add(Calendar.DATE, +1);// 日期加1(包含结束)
            while (tempStart.before(tempEnd)) {
                days.add(dateFormat.format(tempStart.getTime()));
                tempStart.add(Calendar.DAY_OF_YEAR, 1);
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }

        return days;
    }

    /**
     * 将任意类型转换秒级时间戳
     *
     * @param obj
     * @return
     */
    public Integer getIntegerTime(Object obj) {
        if (obj != null) {
            long time = 0;
            if (obj instanceof String) {
                String dateStr = (String) obj;
                if (dateStr.length() > 10) {
                    time = DateFormat.getDate(dateStr).getTime();
                } else {
                    time = DateFormat.getDates(dateStr).getTime();
                }

            }
            if (obj instanceof Date) {
                //不用转了
                Date date = (Date) obj;
                time = date.getTime();

            }
            String str = String.valueOf(time);
            if (str.length() > 10) {
                str = str.substring(0, 10);
            }
            return Integer.parseInt(str);
        }
        return null;
    }

    public static String sendPost(String url, String param) {
        String result = "";
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        CloseableHttpResponse response = null;
        try {
            HttpPost httppost = new HttpPost(url);
            httppost.setHeader("Accept", "application/json");
            httppost.setHeader("Content-Type", "application/json");
            BasicHttpEntity requestBody = new BasicHttpEntity();
            requestBody.setContent(new ByteArrayInputStream(param.getBytes("UTF-8")));
            requestBody.setContentLength(param.getBytes("UTF-8").length);
            httppost.setEntity(requestBody);
// 执行客户端请求
            response = httpClient.execute(httppost);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                result = EntityUtils.toString(entity, "UTF-8");
            }
            //自动释放链接
            EntityUtils.consume(entity);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接
            // httpclient.getConnectionManager().shutdown();
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * @创建作者:李然 Lr
     * @方法描述：分组
     * @创建时间：14:46 2019/4/23
     **/
    public Map<String, List<UserDuty>> groupUserDuty(Set<String> set, List<UserDuty> list) {
        Map<String, List<UserDuty>> map = new HashMap<>();
        for (String pin : set) {
            List<UserDuty> userDutyList = new ArrayList<>();
            for (UserDuty userDuty : list) {
                if (userDuty.getUserId().equals(pin)) {
                    userDutyList.add(userDuty);
                }
            }
            if (userDutyList.size() > 0) {
                map.put(pin, userDutyList);
            }
        }
        if (map.size() > 0) {
            return map;
        }
        return null;
    }

    private void paixuAttend(List<TransactionResponse.DataBean.ItemsBean> dayItemsBeanList) {
        Collections.sort(dayItemsBeanList, new Comparator<TransactionResponse.DataBean.ItemsBean>() {
            @Override
            public int compare(TransactionResponse.DataBean.ItemsBean o1, TransactionResponse.DataBean.ItemsBean o2) {
                try {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    int flag = sdf.parse(o1.getChecktime()).compareTo(sdf.parse(o2.getChecktime()));
                    return flag;
                } catch (Exception e) {
                    System.out.println(e);
                }
                return 0;
            }
        });
    }

}
